﻿using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;

namespace ServerSideTest.StoredProceduresTest
{
    
    /// <summary>
    ///StoredProceduresTest のテスト クラスです。すべての
    ///StoredProceduresTest 単体テストをここに含めます
    ///</summary>
	[TestClass()]
	public partial class StoredProceduresTest
	{
		private TestContext testContextInstance;

		private System.Data.SqlClient.SqlConnection Connection;
		private SqlDirectControl Control;

		private static int IdSeed = 0;

		/// <summary>
		///現在のテストの実行についての情報および機能を
		///提供するテスト コンテキストを取得または設定します。
		///</summary>
		public TestContext TestContext
		{
			get
			{
				return testContextInstance;
			}
			set
			{
				testContextInstance = value;
			}
		}

		[ClassCleanup]
		public static void ClassCleanUp()
		{
			using (SqlDirectControl ctrl = new SqlDirectControl())
			{
				ctrl.MaxTagsCount = 5;
			}
		}

		[TestInitialize()]
		public void MyTestInitialize()
		{
			Connection = new System.Data.SqlClient.SqlConnection(SqlDirectControl.ConStr);
			Connection.Open();

			Control = new SqlDirectControl();

			Control.DeleteAllTable();
		}

		[TestCleanup()]
		public void MyTestCleanup()
		{
			Connection.Close();
			Control.Dispose();
		}
		

		/// <summary>
		///DeleteTag のテスト
		///</summary>
		[TestMethod()]
		public void SimpleDeleteTest()
		{
			string sid = GetStationId();
			string cstr = GetCaster();
			string tag = GetTag();

			Add(sid, cstr, tag);
			Delete(sid, cstr, tag);
			var Result = Control.GetTag(sid, cstr);

			Assert.AreEqual<int>(0, Result.Count());
		}

		[TestMethod]
		public void GetTest()
		{
			string sid = GetStationId();
			string cstr = GetCaster();
			List<string> tags = new List<string>();

			for (int i = 0; i < Control.MaxTagsCount; i++)
			{
				tags.Add(GetTag());
				Add(sid, cstr, tags[i]);
			}

			var Actual = GetTags(sid, cstr);
			var Expected = Control.GetTag(sid, cstr);

			Assert.AreEqual<int>(Expected.Count(), Actual.Count());

			foreach (string act in Actual)
			{
				Assert.AreEqual<int>(1, Expected.Where(tmp => tmp == act).Count());
			}

		}

		[TestMethod]
		public void PartialDeleteTest()
		{
			string sid = GetStationId();
			string cstr = GetCaster();
			string tag = GetTag();

			Add(sid, cstr, tag);
			Delete(null, cstr, tag);
			Delete(sid, null, tag);
			Delete(sid, cstr, null);
			Delete(null, null, null);

			var Expected = Control.GetTag(sid, cstr);
			Assert.AreEqual<int>(1, Expected.Count());
		}

		/// <summary>
		///AddTag のテスト
		///</summary>
		[TestMethod()]
		public void SimpleAddTagTest()
		{
			string sid = GetStationId();
			string cstr = GetCaster();
			string tag = GetTag();

			Add(sid, cstr, tag);

			var Result = Control.GetTag(sid, cstr);

			Assert.AreEqual<int>(1, Result.Count());
			Assert.AreEqual<int>(1, Result.Where(tmp => tmp == tag).Count());
		}

		[TestMethod]
		public void MultiAdd()
		{
			string sid = GetStationId();
			string cstr = GetCaster();
			List<string> tags = new List<string>();

			for (int i = 0; i <Control.MaxTagsCount; i++)
			{
				tags.Add(GetTag());
			}

			var Result = Control.GetTag(sid, cstr);

			foreach (string element in tags)
			{
				Add(sid, cstr, element);
			}

			foreach (var tag in tags)
			{
				Assert.AreEqual<int>(1, Result.Where(tmp => tmp == tag).Count());
			}

			string Additionaltag = GetTag();

			Add(sid, cstr, Additionaltag);
			Result = Control.GetTag(sid, cstr);

			Assert.AreEqual<int>(1, Result.Where(tmp => tmp == Additionaltag).Count());

			string hoge = tags[0];
			Assert.AreEqual<int>(0, Result.Where(tmp => tmp == hoge).Count());

		}

		[TestMethod]
		public void SimpleModify()
		{
			string sid = GetStationId();
			string cstr = GetCaster();
			string ft = GetTag();
			string tt = GetTag();
			Add(sid, cstr, ft);
			Modify(sid, cstr, ft, tt);

			var Result = Control.GetTag(sid, cstr);
			Assert.AreEqual<int>(1, Result.Where(tmp => tmp == tt).Count());
			Assert.AreEqual<int>(0, Result.Where(tmp => tmp == ft).Count());
		}

		[TestMethod]
		public void ComplexModify()
		{
			string sid = GetStationId();
			string cstr = GetCaster();
			string ft = GetTag();
			string tt0 = GetTag();
			string tt1 = GetTag();

			Add(sid, cstr, ft);
			Modify(sid, cstr, ft, tt0);
			Modify(sid, cstr, ft, tt1);

			var Result = Control.GetTag(sid, cstr);

			Assert.AreEqual<int>(1, Result.Where(tmp => tmp == tt0).Count());
			Assert.AreEqual<int>(1, Result.Where(tmp => tmp == tt1).Count());
			Assert.AreEqual<int>(0, Result.Where(tmp => tmp == ft).Count());
		}

		[TestMethod]
		public void OverlapedModifyTest()
		{
			string sid = GetStationId();
			string cstr = GetCaster();
			string tag = GetTag();

			Add(sid, cstr, tag);
			Modify(sid, cstr, tag, tag);

			var Actual = Control.GetTag(sid, cstr);

			Assert.AreEqual<int>(1, Actual.Count());
			Assert.AreEqual<int>(1, Actual.Where(tmp => tmp == tag).Count());

		}

		[TestMethod]
		public void ComplexOverFlowModifyTest()
		{
			string sid = GetStationId();
			string cstr = GetCaster();
			List<string> tags = new List<string>();
			string tt0 = GetTag();
			string tt1 = GetTag();

			for (int i = 0; i < Control.MaxTagsCount; i++)
			{
				tags.Add(GetTag());
				Add(sid, cstr, tags[i]);
			}

			string ft = tags[0];

			Modify(sid, cstr, ft, tt0);
			Modify(sid, cstr, ft, tt1);

			var Result = Control.GetTag(sid, cstr);

			Assert.AreEqual<int>(1, Result.Where(tmp => tmp == tt0).Count());
			Assert.AreEqual<int>(1, Result.Where(tmp => tmp == tt1).Count());
			Assert.AreEqual<int>(0, Result.Where(tmp => tmp == ft).Count());

			ft = tags[1];

			Assert.AreEqual<int>(0, Result.Where(tmp => tmp == ft).Count());
		}

		[TestMethod]
		public void PartialModifyTest0()
		{
			string sid = GetStationId();
			string cstr = GetCaster();
			string ft = GetTag();
			string tt = GetTag();

			Modify(sid, cstr, ft, tt);

			var Result = Control.GetTag(sid, cstr);
			Assert.AreEqual<int>(1, Result.Where(tmp => tmp == tt).Count());
		}

		[TestMethod]
		public void PartialModifyTest1()
		{
			string sid = GetStationId();
			string cstr = GetCaster();
			string ft = GetTag();
			string tt = GetTag();

			Modify(sid, cstr, ft, ft);

			var Result = Control.GetTag(sid, cstr);
			Assert.AreEqual<int>(0, Result.Where(tmp => tmp == ft).Count());
		}

		[TestMethod]
		public void PartialModifyTest2()
		{
			string sid = GetStationId();
			string cstr = GetCaster();
			string ft = GetTag();
			string tt = GetTag();

			Add(sid, cstr, ft);
			Modify(sid, cstr, ft, tt);

			var Result = Control.GetTag(sid, cstr);
			Assert.AreEqual<int>(1, Result.Where(tmp => tmp == tt).Count());
		}

		[TestMethod]
		public void PartialModifyTest3()
		{
			string sid = GetStationId();
			string cstr = GetCaster();
			string ft = GetTag();
			string tt = GetTag();

			Add(sid, cstr, ft);
			Modify(sid, cstr, ft, null);

			var Result = Control.GetTag(sid, cstr);
			Assert.AreEqual<int>(1, Result.Where(tmp => tmp == ft).Count());
			Assert.AreEqual<int>(1, Result.Count());

			Modify(sid, cstr, null, tt);
			Result = Control.GetTag(sid, cstr);
			Assert.AreEqual<int>(1, Result.Where(tmp => tmp == ft).Count());
			Assert.AreEqual<int>(1, Result.Count());


			Modify(null, cstr, ft, tt);
			Result = Control.GetTag(sid, cstr);
			Assert.AreEqual<int>(1, Result.Where(tmp => tmp == ft).Count());
			Assert.AreEqual<int>(1, Result.Count());

			Modify(sid, null, ft, tt);
			Result = Control.GetTag(sid, cstr);
			Assert.AreEqual<int>(1, Result.Where(tmp => tmp == ft).Count());
			Assert.AreEqual<int>(1, Result.Count());

			Modify(null, null, null, null);
			Result = Control.GetTag(sid, cstr);
			Assert.AreEqual<int>(1, Result.Where(tmp => tmp == ft).Count());
			Assert.AreEqual<int>(1, Result.Count());

		}

		[TestMethod]
		public void PartialValueAdd()
		{
			Add(null, "hoge", "piyo");
			IsNoRecord();

			Add("hoge", null, "piyo");
			IsNoRecord();

			Add("hoge", "piyo", null);
			IsNoRecord();
		}


	}
}
